/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package jocabulary;

import java.io.*;
import java.util.*;

import javax.xml.parsers.*;
import org.xml.sax.*;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author pit
 */
public class Jocabulary_Controller extends DefaultHandler {

    private Jocabulary_GUI theGUI;
    private FileDownloader fd = new FileDownloader();

    private String baseFolder = "data/";

    private ArrayList languages = new ArrayList();

    private int selectedLanguage;
    private int selectedItem;
    private Unit selectedUnit;


    private Vocable currentVocable;
    private boolean answerShowing;
    private boolean listDone;
    private int totalCorrect;
    private int totalWrong;
    
    private Random r = new Random();
    private int randomOrder;

    private int settingOrder; // 0 = Random, 1 = Native->Other, 2 = Other->Native

    private String tempVal;
    private String tempItemName;
    private int tempRevision;
    private Language tempLang;

    Jocabulary_Controller(Jocabulary_GUI pGUI) {
        theGUI = pGUI;

        File f = new File(baseFolder);
        if(!f.isDirectory())
            f.mkdir();

        fd.downloadFile("files.xml");
        parseLanguages();
        updateLanguages();
    }

    private void updateLanguages() {
        theGUI.clearLanguages();
        for(int i=0; i<languages.size(); i++) {
            Language l = (Language) languages.get(i);
            theGUI.addLanguage(l.getCleanName());
        }
        selectLanguage(0);
    }
    public void updateItems() {
        theGUI.clearItems();
        Language l = (Language) languages.get(selectedLanguage);
        for(int i=0; i<l.getUnitCount(); i++) {
            theGUI.addItem(l.getUnit(i).getCleanName());
        }
        selectItem(0);
    }

    public void selectLanguage(int index) {
        selectedLanguage = index;
        updateItems();
        theGUI.rbNativeToTranslation_setText("Deutsch - " + ((Language) languages.get(index)).getCleanName());
        theGUI.rbTranslationToNative_setText(((Language) languages.get(index)).getCleanName() + " - Deutsch");
        theGUI.enableItems(true);
    }
    public void selectItem(int index) {
        selectedItem = index;
        theGUI.enableSettings(true);
        theGUI.enableAskAndStats(false);
    }

    private void parseLanguages() {
        SAXParserFactory spf = SAXParserFactory.newInstance();

        try {
            SAXParser sp = spf.newSAXParser();
            sp.parse(baseFolder+"files.xml", this);
        } catch(Exception e) {
            System.out.println(e);
        }
    }

    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        tempVal = "";
        tempItemName = "";

        if(qName.equalsIgnoreCase("Language")) {
            tempLang = new Language(attributes.getValue("name"), attributes.getValue("cleanname"));
        } else if(qName.equalsIgnoreCase("Item")) {
            tempItemName = attributes.getValue("name");
            tempRevision = Integer.parseInt(attributes.getValue("revision"));
        }
    }
    public void characters(char[] ch, int start, int length) throws SAXException {
        tempVal = new String(ch, start, length);
    }
    public void endElement(String uri, String localName, String qName) throws SAXException {
        if(qName.equalsIgnoreCase("Language")) {
            languages.add(tempLang);
        } else if(qName.equalsIgnoreCase("Item")) {
            try { tempLang.addUnit(tempItemName, tempVal, tempRevision); } catch(IOException e) { System.out.println(e); }
        }
    }

    public void start(int pOrder, int pTimesCorrect, boolean pRequired, boolean pRandomAskOrder) {
        theGUI.enableAskAndStats(true);
        theGUI.listDone(false);

        settingOrder = pOrder;
        totalCorrect = 0;
        totalWrong = 0;

        Language l = (Language) languages.get(selectedLanguage);
        selectedUnit = l.getUnit(selectedItem);
        selectedUnit.loadVocab();

        selectedUnit.prepareQuestions(pTimesCorrect, pRequired, pRandomAskOrder);
        theGUI.setProgress(selectedUnit.getAskedCount(), selectedUnit.getVocabCount());
        askNextVocable();
    }
    public void actionPerformed(String pTranslation) {
        if(answerShowing) {
            askNextVocable();
        } else {
            validateAnswer(pTranslation);
        }
    }
    public void askNextVocable() {
        try {
            currentVocable = selectedUnit.getNextVocable();
            answerShowing = false;

            if(settingOrder == 0)
                randomOrder = r.nextInt(2) + 1;
            else
                randomOrder = settingOrder;

            if(randomOrder == 1) { // Native->Other
                theGUI.askVocable(currentVocable.getNativeWord());
            } else if(randomOrder == 2) { // Other->Native
                theGUI.askVocable(currentVocable.getTranslation());
            }
            theGUI.setStats(currentVocable.getTimesCorrect(), totalCorrect, totalWrong);
        } catch (Exception e) { // Random
            done();
        }
    }
    public void validateAnswer(String pTranslation) {
        System.out.println(currentVocable.getAlternativeTranslation());
        answerShowing = true;

        if(randomOrder == 1) { // Native->Other
            if((pTranslation.equalsIgnoreCase(currentVocable.getTranslation())) || (!currentVocable.getAlternativeTranslation().equalsIgnoreCase("") && pTranslation.equalsIgnoreCase(currentVocable.getAlternativeTranslation()))) {
                currentVocable.answer(true);
                theGUI.answerCorrect();
                totalCorrect++;
            } else {
                currentVocable.answer(false);
                theGUI.answerWrong(currentVocable.getTranslation());
                totalWrong++;
            }
        } else if(randomOrder == 2) { // Other->Native
            if(pTranslation.equalsIgnoreCase(currentVocable.getNativeWord())) {
                currentVocable.answer(true);
                theGUI.answerCorrect();
                totalCorrect++;
            } else {
                currentVocable.answer(false);
                theGUI.answerWrong(currentVocable.getNativeWord());
                totalWrong++;
            }
        }
        theGUI.setStats(currentVocable.getTimesCorrect(), totalCorrect, totalWrong);
        theGUI.setProgress(selectedUnit.getAskedCount(), selectedUnit.getVocabCount());
    }
    private void done() {
        listDone = true;
        stop();
    }
    public void stop() {
        if(listDone) {
            theGUI.listDone(true);
            listDone = false;
        }
        selectedUnit.writeFile();
        theGUI.clearFields();
        theGUI.tbtnStartSetSelected(false);
        theGUI.enableAskAndStats(false);
        theGUI.setProgress(0, 0);
    }

}
